package com.treasure.service.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
import org.springframework.core.annotation.Order;


/**
* @Description:    队列配置
* @Author:         panxinwen
* @CreateDate:     2018/11/1 21:17
* @Version:        1.0
*/
@Configuration
@EnableRabbit
@SuppressWarnings("SpringJavaAutowiringInspection")
@Order(1)
public class RabbitMQConfigration {
    Logger logger = LoggerFactory.getLogger(RabbitMQConfigration.class);

    @Autowired
    private MQProperties mqProperties;

    @Autowired
    @Qualifier("rabbitConnectionFactory")
    private ConnectionFactory rabbitConnectionFactory;
    @Autowired
    @Qualifier("rabbitAdmin")
    private RabbitAdmin rabbitAdmin;

    @Bean(name = "rabbitConnectionFactory")
    @Primary
    public ConnectionFactory rabbitConnectionFactory(
        @Value("${spring.rabbitmq.host}") String host,
        @Value("${spring.rabbitmq.port}") int port,
        @Value("${spring.rabbitmq.username}") String username,
        @Value("${spring.rabbitmq.password}") String password,
        @Value("${spring.rabbitmq.virtual-host}") String virtualHost) {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setHost(host);
        connectionFactory.setPort(port);
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        connectionFactory.setVirtualHost(virtualHost);
        return connectionFactory;
    }

    /**
     * 针对消费者配置
     * FanoutExchange: 将消息分发到所有的绑定队列，无routingkey的概念
     * HeadersExchange ：通过添加属性key-value匹配
     * DirectExchange:按照routingkey分发到指定队列
     * TopicExchange:多关键字匹配
     */
    @Bean
    @ConditionalOnProperty(name = "mq.config.default-direct-exchange", relaxedNames = true)
    public DirectExchange defaultDirectExchange() {
        logger.info("初始化defaultDirectExchange:{}", mqProperties.getDefaultDirectExchange());
        DirectExchange directExchange = new DirectExchange(mqProperties.getDefaultDirectExchange(), true, false);
        rabbitAdmin.declareExchange(directExchange);
        return directExchange;
    }

    @Bean
    @ConditionalOnProperty(name = "mq.config.default-topic-exchange", relaxedNames = true)
    public TopicExchange defaltTopicExchange() {
        logger.info("初始化defaultTopicExchange:{}", mqProperties.getDefaultTopicExchange());
        TopicExchange topicExchange = new TopicExchange(mqProperties.getDefaultTopicExchange(), true, false);
        rabbitAdmin.declareExchange(topicExchange);
        return topicExchange;
    }

    @Bean("rabbitAdmin")
    public RabbitAdmin admin() {
        return new RabbitAdmin(rabbitConnectionFactory);
    }

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)//必须是prototype类型
    public RabbitTemplate rabbitTemplate() {
        logger.info("########################初始化rabitTemplate################################");
        RabbitTemplate r = new RabbitTemplate(rabbitConnectionFactory);
        r.setExchange(mqProperties.getDefaultTopicExchange());
        return r;
    }

    @Bean
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
        logger.info("########################初始化rabbitListenerContainerFactory################################");
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(rabbitConnectionFactory);
        factory.setMessageConverter(new Jackson2JsonMessageConverter());
        return factory;
    }

    /**
     * 创建信用卡办理结果 消费队列
     * @return
     */
    @Bean
    @ConditionalOnProperty(name = "mq.config.yg-rrg-mq-coupon-qruey",relaxedNames = true)
    public Queue cardDisposeResultQueue() {
        logger.info("创建 推送到攘攘谷用户投资信息 生产者监听队列：{}", mqProperties.getCardDisposeResultQueue());
        return new Queue(mqProperties.getCardDisposeResultQueue(), true); // 队列持久
    }

    /**
     *  绑定信用卡办理结果
     * @return
     */
    @Bean
    @ConditionalOnBean(name = "cardDisposeResultQueue")
    public Binding bindingCardDisposeResultQueue(){
        logger.info("监听攘攘谷优惠券 mq 绑定队列，exchange:{},routingKey:{},queueName:{}", defaltTopicExchange(), mqProperties.getCardDisposeResultKey(), mqProperties.getCardDisposeResultQueue());
        return BindingBuilder.bind(cardDisposeResultQueue()).to(defaltTopicExchange()).with(mqProperties.getCardDisposeResultKey());
    }

}
